Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Πρόβλημα με Binding

Îåêßíçóå áðü ôï ìÝëïò AlKiS. Τελευταία δημοσίευση από το μέλος AlKiS στις 31-12-2011, 20:09. Υπάρχουν 7 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  29-12-2011, 16:14 68735

    Πρόβλημα με Binding

    Καλησπέρα αγαπητή κοινότητα του dotNetZone.


    Έχω μια φόρμα, η οποία έχει ένα κουμπί, και μετατρέπει όσα αρχεία Excel είναι σε ένα συγκεκριμένο φάκελο, σε αρχεία κειμένου .txt.

    Για να κάνω το πρόγραμμά μου να επικοινωνεί με το Excel, είχα συμβουλευτεί ξανά το φόρουμ, και έμαθα τα εξής:

    1) Refference sto "office" kai sto "Microsoft.Office.Interop.Excel1"

    2)     Public ExcelRead As New Microsoft.Office.Interop.Excel.Application()     Dim ExcelWorkbook As Microsoft.Office.Interop.Excel.Workbook     Dim ExcelWorksheet As Microsoft.Office.Interop.Excel.Worksheet

    Τα οποία έχω στο (Declerations) ώστε να είναι ορατά από όλα τα κουμπιά ή λειτουργίες.

    3)             ExcelRead.FileValidation = Microsoft.Office.Core.MsoFileValidationMode.msoFileValidationSkip

    Το οποίο είναι στη στο frmTransform_Load

    Η Χρησιμότητα του οποίου είναι: Τα αρχεία που μετατρέπω βγάζουν πρόβλημα Protected View κτλ, και ότι ίσως είναι κακόβουλο αρχείο και βλακείες (ξέρω ότι δεν είναι). Αλλα για να περάσει αυτή τη βλακεία το πρόγραμμα όμως, μου είπαν να χρησιμοποιήσω το παραπάνω κώδικα. Το έκανα και δουλεύει.


    Το θέμα είναι όμως, οτι τώρα που έβαλα Option String On, μου βγάζει πρόβλημα στο  "ExcelRead.FileValidation = Microsoft.Office.Core.MsoFileValidationMode.msoFileValidationSkip"  το οποίο είναι το εξής:

    "Option String On disallows late binding"

    Το ίδιο μήνυμα μου βγάζει και μεσα στο κουμπί που κάνει την μετατροπή, σε σειρές όπως:

    Do While ExcelWorksheet.Cells(iRow, 1).Value <> Nothing
    ή όπως:
    NewLine = NewLine & ExcelWorksheet.Cells(iRow, iColumn).Value & " "

    Τι είναι το Binding. Ξέρω ότι Bind στα αγγλικά σημαίνει Δένω, αλλά δεν μου λέει κάτι στα προγραμματιστικά...
    Τι είναι?? και πως να περάσω το πρόβλημα αυτό??


  •  29-12-2011, 19:13 68737 σε απάντηση της 68735

    Απ: Πρόβλημα με Binding

    Χονδρικά και απλά:

    Early Binding είναι όταν ο compiler ξέρει τον τύπο μιας μεταβλητής κατά το compilation. Late Binding είναι όταν δεν τον ξέρει και τον "μαθαίνει" κατά το runtime. Για παράδειγμα, late binding είναι το παρακάτω:

    Dim something as Object
    something = DateTime.Now

    Θα δεις ότι στη συνέχεια μπορείς να πεις

    something.souloumoutzoukoumtsitsiri = 123

    και το πρόγραμμα θα κάνει compile μια χαρά (θα σκάσει όμως κατά το runtime). Επίσης θα παρατηρήσεις ότι το intellisense δεν θα σου κάνει list τα properties και τα methods ακόμα και αν το souloumoutzoukoumtsitsiri είναι ένα υπαρκτό property.

    Όταν δουλεύεις με COM interop (όπως στην περίπτωσή σου με το Excel) τότε χρησιμοποιείς late binding έστω κι αν λες όταν δηλώνεις μια μεταβλητή "As Microsoft.Office.Interop.Excel.Workbook"

    Τώρα, προφανώς κάποιος σου είπε ότι πρέπει να βάζουμε Option Strict On για να αποφεύγουμε διάφορα προβλήματα, πράγμα πάρα πολύ σωστό, ωστόσο το Option Strict On δεν επιτρέπει το late binding, που σημαίνει ότι θα πρέπει να το βγάλεις για το file μέσα στο οποίο έχεις τον Excel interop κώδικα. Συνήθως, όταν γράφουμε COM interop κώδικα, τον διαχωρίζουμε φυσικά και λογικά από τον υπόλοιπο κώδικα ώστε να έχουμε Option Strict Off και στον υπόλοιπο κώδικα έχουμε Option Strict On.

     


    Vir prudens non contra ventum mingit
  •  29-12-2011, 19:35 68738 σε απάντηση της 68737

    Απ: Πρόβλημα με Binding

    Άρα λοιπών δεν είναι ότι έκανα κάποιο λάθος, αλλά είναι αναγκαίο late binding σε αυτή την περίπτωση.

    Δεν το ήξερα αυτό

    Θα ακολουθήσω την συμβουλή σου λοιπών και θα διαχωρίσω τον interoperative κώδικα ώστε να ανοίξω το option strict στην φόρμα.


     σε ευχαριστώ πολύ :)

    (p.s. έβαλα το πόστ σαν επιλυμένο ) 



  •  29-12-2011, 23:19 68740 σε απάντηση της 68735

    Απ: Πρόβλημα με Binding

    Ναι το late Binding είναι απαραίτητο μερικές φορές όπως σου απάντησε ο Kelman. Αυτό που θέλω να σου επισημάνω έχει να κάνει με τον τρόπο που θα ανοίγεις και θα κλείνεις τα Excel αρχεία.

    1. Οπωσδήποτε να καλείς την Quit πχ, ExcelRead.Quit. Αν δεν το κάνεις αυτό θα γεμίσεις την Μνήμη με Excel processes που δεν θα σβήνονται από την μνήμη ακόμα και αν κλείσεις την εφαρμογή σου.

    2. Αν το Function που ανοίγει το Excel καλείται πάρα πολλές φορές, η μνήμη θα γεμίζει με processes τoυ Excel. Γιά να το δεις αυτό άνοιξε τον Task Manager και πήγαινε στο Processes Tab. Αν νομίζεις ότι αυτό θα σου δημιουργήσει πρόβλημα ή κράτα στην μνήμη ένα Excel application ή Χρησιμοποίησε την System.Runtime.InteropServices.Marshal.ReleaseComObject (την οποία εύχομαι να μην χρειαστεί να χρησιμοποίησεις).

    Το παρακάτω παράδειγμα δείχνει πως μπορεί να γίνονται συνέχεια instances του Excel ενώ εμείς νομίζουμε ότι όλα πάνε καλά. Το πρόβλημα το δημιουργεί η Dim wBook As Microsoft.Office.Interop.Excel.Workbook = xcel.Workbooks.Open("C:\Users\Vangelis\Downloads\TEST.xlsx"). Το σωστό είναι να φτιάχνουμε κάθε φορά μία μεταβλητή στην κάθε περίπτωση που χρειαζόμαστε να έχουμε πρόσβαση σε properties ή methods ενός Com object και να την κάνουμε release μετά την χρήση της.
    http://support.microsoft.com/kb/317109

    Παράδειγμα:

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim xcel As New Excel.Application() With {.FileValidation = Microsoft.Office.Core.MsoFileValidationMode.msoFileValidationSkip}
            Dim wBooks As Excel.Workbooks = xcel.Workbooks
            ''Dim wBook As Microsoft.Office.Interop.Excel.Workbook = wBooks.Open("C:\Users\Vangelis\Downloads\TEST.xlsx") ' ΣΩΣΤΟ
            Dim wBook As Microsoft.Office.Interop.Excel.Workbook = xcel.Workbooks.Open("C:\Users\Vangelis\Downloads\TEST.xlsx") ' ΛΑΘΟΣ! 
            ' Δεν θα σβήνει τα excel processes ενώ τρέχει το πρόγραμμα ακόμα και με την Quit.
            Dim wSheet As Microsoft.Office.Interop.Excel.Worksheet = CType(xcel.ActiveSheet, Microsoft.Office.Interop.Excel.Worksheet)
    
            System.Runtime.InteropServices.Marshal.ReleaseComObject(wSheet) ' Απαραίτητο
            wSheet = Nothing ' To nothing είναι πάντα της μόδας
    
            Marshal.ReleaseComObject(wBook)
            wBook = Nothing
    
            Marshal.ReleaseComObject(wBooks) ' Απαραίτητο
            wBooks = Nothing
    
            xcel.Quit() ' Απαραίτητο
            Marshal.ReleaseComObject(xcel) ' Απαραίτητο
            xcel = Nothing
        End Sub

     

     

  •  29-12-2011, 23:38 68741 σε απάντηση της 68740

    Απ: Πρόβλημα με Binding

    wow, υπάρχουν πολλά σε αυτά που έγραψες που δεν ήξερα και δεν χρησιμοποιούσα.

    επειδή απο το πρωί όμως προγραμματίζω ασταμάτητα - δεν έχω κουράγιο να κάνω αλλαγές σήμερα.

    Αύριο θα ενσωματώσω τα καινούργια πράγματα και θα κάνω reply με τις αλλαγές που έκανα για να δούμε αν τα έχω προγραμματιστικά καλά ή όχι.


    Thank you very much! and good night :)


  •  31-12-2011, 12:42 68751 σε απάντηση της 68741

    Απ: Πρόβλημα με Binding

    Έκανα τις αλλαγές αλλά έχω πρόβλημα..

    1) το With {.FileValidation = Microsoft.Office.Core.MsoFileValidationMode.msoFileValidationSkip} δεν δουλεύει. Μου λέει Option Strict Disallows Late Binding ακόμα κιαν πάνω πάνω στη σελίδα έβαλα Option Strict OFF for god's sake :S τέσπα δν πειράζει το έχω στο MyBase.Load.

    2) To EXCEL συνεχίζει να μην σβήνει με το κλείσιμο της φόρμας..

    Αυτό που γίνεται είναι ότι όταν ολόκληρο το πρόγραμμα κλείσει, σβήνει και το excel, όπως και πριν.

    Τι έκανα λάθος?


    Επειδή ο κώδικας είναι πολύ μεγάλος για να τον γράψω εδώ, παρακαλώ δείτε τον απο εδώ:

    http://dl.dropbox.com/u/18135227/frmTransform.rar (Είναι direct link, δεν χρειάζεται ούτε κωδικούς ούτε περίμενε 5 δευτερόλεπτα ούτε τπτ)

    το αρχείο είναι 37ΚΒ.


    Ευχαριστώ


  •  31-12-2011, 19:52 68753 σε απάντηση της 68751

    Απ: Πρόβλημα με Binding

    1) το With {.FileValidation = Microsoft.Office.Core.MsoFileValidationMode.msoFileValidationSkip} δεν δουλεύει. Μου λέει Option Strict Disallows Late Binding ακόμα κιαν πάνω πάνω στη σελίδα έβαλα Option Strict OFF for god's sake :S τέσπα δν πειράζει το έχω στο MyBase.Load.

    - Πειράζει. Βεβαιώσου ότι τα version των assemblies είναι 14.0.0.0. (Κάνεις access ένα property που δεν υπάρχει σε άλλα versions).

    2) To EXCEL συνεχίζει να μην σβήνει με το κλείσιμο της φόρμας..

    Αυτό που γίνεται είναι ότι όταν ολόκληρο το πρόγραμμα κλείσει, σβήνει και το excel, όπως και πριν.

    - Δεν πειράζει (πολύ)  αυτό που μας ενδιαφέρει άμεσα είναι να κλείνει όταν κλείνει η εφαρμογή.

    Τι έκανα λάθος?

    Το Automation θέλει πολλή προσοχή από τον προγραμματιστή. Π.χ Προσθέτωντας ένα απλό loop στο στο προηγούμενο παράδειγμα δεν κλέινει το Excel process. (Μην ανησυχείς αυτό που σε νοιάζει είναι να κλείνει to Excel process όταν κλέινει το πρόγραμμα. Φτιάξε ένα Excel app και δούλευε με αυτό.)

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim xcel As New Excel.Application() With {.FileValidation = Microsoft.Office.Core.MsoFileValidationMode.msoFileValidationSkip}
            Dim wBooks As Excel.Workbooks = xcel.Workbooks
            Dim wBook As Microsoft.Office.Interop.Excel.Workbook = wBooks.Open("C:\Users\Vangelis\Downloads\TEST.xlsx")
            Dim wSheet As Microsoft.Office.Interop.Excel.Worksheet = CType(xcel.ActiveSheet, Microsoft.Office.Interop.Excel.Worksheet)
    
            ' Βάζωντας αυτό το απλό loop Δεν κλείνει το Excel process.
            For Each row As Excel.Range In wSheet.UsedRange
                Dim oVal As Object = row.Value2
            Next
    
            System.Runtime.InteropServices.Marshal.ReleaseComObject(wSheet) ' Απαραίτητο
            wSheet = Nothing ' To nothing είναι πάντα της μόδας
    
            Marshal.ReleaseComObject(wBook)
            wBook = Nothing
    
            Marshal.ReleaseComObject(wBooks) ' Απαραίτητο
            wBooks = Nothing
    
            xcel.Quit() ' Απαραίτητο
            Marshal.ReleaseComObject(xcel) ' Απαραίτητο
            xcel = Nothing
        End Sub

     

     

     

  •  31-12-2011, 20:09 68754 σε απάντηση της 68753

    Απ: Πρόβλημα με Binding

    A, okay τότε.

    Ευχαριστώ :)

    p.s. βάζω το thread σαν επιλυμένο.


Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems